package uk.ac.aber.Blockmation;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;

import javax.swing.JPanel;

public class Display extends JPanel {
	
    final static int WIDTH = 20;
    final static int HEIGHT = 20;
    final static Dimension BLOCK_DEFAULT = new Dimension(15, 15);
    final static Color BACKGROUND = Color.white;
    private BufferedImage image;
    private Dimension block;
    private AffineTransform at = new AffineTransform();
    private Color background;
	
	
    public Display()
    {
        this(BACKGROUND);
    }
    
    public Display(Color background)
    {
        this.background = background;
    	block = BLOCK_DEFAULT;
    	// to create a compatible image?
        setImage( new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB) );
        this.setPreferredSize(new Dimension(image.getWidth(), image.getHeight()));
        clear();
    }
      
    public void clear()
    {
        Graphics2D g2;
        g2 = image.createGraphics();
        g2.setColor(background);
        g2.fillRect(0, 0, image.getWidth(), image.getHeight());
        g2.drawImage(image, null, 0, 0);
        g2.dispose();
        
        repaint();
    }
	
	
    public void paint(Graphics g)
    {
        super.paint(g);

        Graphics2D g2 = (Graphics2D) g;

        if (image != null)
        {
            g2.drawImage(image, null, 0, 0);
        }
    }
	
	
    public void setImage(BufferedImage newImage)
    {
        // resize up to the block size;
        // notify about the change the app like the thumbnails 
        at.setToScale(block.getWidth(), block.getHeight());

        try
        {
        	image = new BufferedImage(newImage.getWidth() * block.width,
                newImage.getHeight() * block.height, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2 = image.createGraphics();
            // draw newImage onto image using at transformation
            g2.drawImage(newImage, at, null);
            g2.dispose();
        } catch (OutOfMemoryError err)
        {
        	System.err.println("Not enough memory for Java Virtual Machine. " +
        			"Allow more memory or refrain from processing. " +        			 
        			"Solution: http://hausheer.osola.com/docs/5");
        	
        }

        //this.image = newImage; without zoom
        this.setPreferredSize(new Dimension(image.getWidth(), image.getHeight()));
        repaint();
    }
	
    public BufferedImage getImage()
    {
        at.setToScale(1/block.getWidth(), 1/block.getHeight());

        BufferedImage imageOut = new BufferedImage(image.getWidth() / block.width,
                image.getHeight() / block.height, BufferedImage.TYPE_INT_RGB);

        Graphics2D g2 = imageOut.createGraphics();
        // draw newImage onto image using at transformation
        g2.drawImage(image, at, null);
        g2.dispose();

        return imageOut;
    }
    
    public BufferedImage getDisplayedImage()
    {
    	return image;
    }
    // doesn't work well for small blocks :/
    public void setBlockSize(Dimension newSize)
    {
     	if (newSize.width > 0 && newSize.width <= 195 &&
     			newSize.height > 0 && newSize.height <= 195)
     	{
        	BufferedImage original = getImage();
        	
        	this.block = newSize;
        	
        	setImage(original);
        	
            this.setPreferredSize(new Dimension(image.getWidth(), image.getHeight()));
            repaint();
     		
     	} else 
     	{
     		System.err.println("Dimension of blocks must be: > 0, <= 195");
     	}
    }
    
    public Dimension getBlockSize()
    {
    	return this.block;
    }

	public Color getBackgroundColor() {
		return background;
	}
	
}
